{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "9d086990",
   "metadata": {},
   "source": [
    "# PyTorch基础数据操作"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "5702d925",
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "4fe33148",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = torch.arange(12)\n",
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "cda9bc46",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "torch.Size([12])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "0810c186",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "device(type='cpu')"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x.device"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "ae9218fb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "12"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x.numel()  # number of elements"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "bd016a9f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[ 0,  1,  2,  3],\n",
       "        [ 4,  5,  6,  7],\n",
       "        [ 8,  9, 10, 11]])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X = x.reshape(3,4)\n",
    "X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "33ec4f2d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]]])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "torch.zeros((2,3,4))\n",
    "torch.ones((2,3,4))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "62b2cb89",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[1, 2, 3],\n",
       "        [4, 5, 6]])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "torch.tensor([[1,2,3],[4,5,6]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "c3a6feb8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([11., 12., 13.]),\n",
       " tensor([10., 20., 30.]),\n",
       " tensor([0.1000, 0.2000, 0.3000]),\n",
       " tensor([  10.,  100., 1000.]))"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 常见标准运算（+ - * / **）都是按元素运算\n",
    "x = torch.tensor([1.0,2,3])  ## 在tensor中任意一个数加一个小数点，就可以把tensor类型转化为float浮点型\n",
    "y = torch.tensor([10,10,10])\n",
    "x + y, x * y, x / y, y ** x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "da26fc28",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[0., 1., 2., 3., 4.],\n",
       "         [5., 6., 7., 8., 9.]]),\n",
       " tensor([[0., 0., 0., 0., 0.],\n",
       "         [0., 0., 0., 0., 0.]]))"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# tensor的拼接\n",
    "x = torch.arange(10,dtype=torch.float32).reshape(2,5)\n",
    "y = torch.zeros(10,dtype=torch.float32).reshape(2,5)\n",
    "x,y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "37d1b7ef",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[0., 1., 2., 3., 4.],\n",
       "         [5., 6., 7., 8., 9.],\n",
       "         [0., 0., 0., 0., 0.],\n",
       "         [0., 0., 0., 0., 0.]]),\n",
       " tensor([[0., 1., 2., 3., 4., 0., 0., 0., 0., 0.],\n",
       "         [5., 6., 7., 8., 9., 0., 0., 0., 0., 0.]]))"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "torch.cat([x,y],dim=0), torch.cat([x,y],dim=1) # dim=0按行拼接，dim=1按列拼接"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "ba36dc4e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[ True, False, False, False, False],\n",
       "        [False, False, False, False, False]])"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 逻辑运算符\n",
    "x == y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "7ef8cbb3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[0],\n",
       "         [1],\n",
       "         [2]]),\n",
       " tensor([[0, 1]]))"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 即时形状不同（但维数得相同），也可以通过“广播机制”来进行运算（按元素）\n",
    "# 具体做法是，通过复制得到各自的一个大张量，然后再逐元素运算\n",
    "# 比如一个(3,1)一个(1,2)，则需要先都统一成(3,2)的矩阵，再计算\n",
    "a = torch.arange(3).reshape(3,1)\n",
    "b = torch.arange(2).reshape(1,2)\n",
    "a,b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "7924e822",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[0, 1],\n",
       "        [1, 2],\n",
       "        [2, 3]])"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a + b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "id": "c7b1c5ce",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[0, 1],\n",
       "         [2, 3],\n",
       "         [4, 5]]),\n",
       " tensor([0, 1]),\n",
       " tensor([[0],\n",
       "         [1]]),\n",
       " tensor([[0, 1]]))"
      ]
     },
     "execution_count": 82,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = torch.arange(6).reshape(3,2)\n",
    "b = torch.arange(2)\n",
    "c = b.reshape(2,1)\n",
    "d = b.reshape(1,2)\n",
    "a,b,c,d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "id": "682d063d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[1],\n",
       "        [3],\n",
       "        [5]])"
      ]
     },
     "execution_count": 85,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# * torch.dot torch.matmul torch.mm这些乘法都是怎样的：\n",
    "\n",
    "a*b\n",
    "# tensor([[0, 1],\n",
    "#         [0, 3],\n",
    "#         [0, 5]])\n",
    "\n",
    "torch.dot(a,b)\n",
    "# RuntimeError: 1D tensors expected, but got 2D and 1D tensors\n",
    "    \n",
    "torch.matmul(a,b)\n",
    "# tensor([1, 3, 5])\n",
    "\n",
    "torch.mm(a,b)\n",
    "# RuntimeError: mat2 must be a matrix\n",
    "\n",
    "torch.matmul(a,c)\n",
    "# tensor([[1],\n",
    "#         [3],\n",
    "#         [5]])\n",
    "\n",
    "torch.mm(a,c)\n",
    "# tensor([[1],\n",
    "#         [3],\n",
    "#         [5]])\n",
    "\n",
    "torch.matmul(a,d)\n",
    "torch.mm(a,d)\n",
    "# RuntimeError: mat1 and mat2 shapes cannot be multiplied (3x2 and 1x2)\n",
    "\n",
    "torch.matmul(a,d.T)\n",
    "torch.mm(a,d.T)\n",
    "# tensor([[1],\n",
    "#         [3],\n",
    "#         [5]])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d28f4c36",
   "metadata": {},
   "source": [
    "### 总结一下：\n",
    "- `*`就是逐元素相乘，采用broadcast机制，还可以使用torch.mul\n",
    "- `.dot`只能用于两个1D向量做内积\n",
    "- `.mm`只能用于两个2D的矩阵相乘，必须符合矩阵乘法的规则\n",
    "- `.matmul`用途最广泛，兼容性最强。可以对1D，2D以及更高维数据进行乘法。当其中有1D时，采用broadcast，当都是2D时使用矩阵乘法规则。还可以使用 `@`符号。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1ea2c991",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 赋值，可以对一个点或者一个区域赋值\n",
    "x\n",
    "# tensor([[0., 1., 2., 3., 4.],\n",
    "#         [5., 6., 7., 8., 9.]])\n",
    "x[1,2] = 100\n",
    "x\n",
    "# tensor([[  0.,   1.,   2.,   3.,   4.],\n",
    "#         [  5.,   6., 100.,   8.,   9.]])\n",
    "x[0, :] = 100\n",
    "x\n",
    "# tensor([[100., 100., 100., 100., 100.],\n",
    "#         [  5.,   6., 100.,   8.,   9.]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "0f796d47",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4694868480\n",
      "5230995712\n"
     ]
    }
   ],
   "source": [
    "p = torch.arange(5)\n",
    "orig_id = id(p)  # id是python自带函数，查询变量的内存地址，相当于指针\n",
    "p = p + 1  # 这样赋值，会分配新的内存地址，导致占用更多内存\n",
    "new_id = id(p)\n",
    "print(orig_id)\n",
    "print(new_id)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "f32f639f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5230929408\n",
      "5230929408\n"
     ]
    }
   ],
   "source": [
    "p = torch.arange(5)\n",
    "orig_id = id(p)\n",
    "p[:] = p + 1  # 使用:符号来赋值，就可以原地进行赋值，不占用新内存\n",
    "new_id = id(p)\n",
    "print(orig_id)\n",
    "print(new_id)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "73774f53",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5231238656\n",
      "5231238656\n"
     ]
    }
   ],
   "source": [
    "p = torch.arange(5)\n",
    "orig_id = id(p)\n",
    "p += 1  # 使用 += 这样的方式在运算，也可以进行原地赋值\n",
    "new_id = id(p)\n",
    "print(orig_id)\n",
    "print(new_id)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "4a23af46",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(numpy.ndarray, torch.Tensor)"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 转换为numpy张量，从numpy张量转化成torch的tensor\n",
    "A = x.numpy()\n",
    "B = torch.tensor(A)\n",
    "type(A), type(B)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "8afe642f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor(3.5000), <function Tensor.item>, 3.5, 3)"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 将大小为1的张量，转换为Python标量\n",
    "# 两种方式：.item 或者 float()/int()\n",
    "a = torch.tensor(3.5)\n",
    "a, a.item, float(a), int(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d3486883",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 当x是一个向量或张量时，就没法使用.item了\n",
    "x.item()\n",
    "# ValueError: only one element tensors can be converted to Python scalars"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "78b3c59d",
   "metadata": {},
   "source": [
    "# 数据预处理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "id": "47bd8d73",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "      <th>C</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1.0</td>\n",
       "      <td>2.0</td>\n",
       "      <td>good</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>4.0</td>\n",
       "      <td>5.0</td>\n",
       "      <td>None</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>10.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>None</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      A     B     C\n",
       "0   1.0   2.0  good\n",
       "1   4.0   5.0  None\n",
       "2  10.0  10.0  None"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "columns = ['A','B','C']\n",
    "data = [[1.,2.,'good'],[4,5],[10,10]]\n",
    "df = pd.DataFrame(data, columns=columns)\n",
    "df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "id": "91dbcf28",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1.0, 2.0, 'good'],\n",
       "       [4.0, 5.0, None],\n",
       "       [10.0, 10.0, None]], dtype=object)"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "id": "42b811df",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "      <th>C_good</th>\n",
       "      <th>C_nan</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1.0</td>\n",
       "      <td>2.0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>4.0</td>\n",
       "      <td>5.0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>10.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      A     B  C_good  C_nan\n",
       "0   1.0   2.0       1      0\n",
       "1   4.0   5.0       0      1\n",
       "2  10.0  10.0       0      1"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "inputs = pd.get_dummies(df,dummy_na=True)  # 通过这种方法，可以将缺失值转化成0，1特征（一般是非数值特征这样做，数值化的特征就直接fillna即可）\n",
    "inputs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "id": "10608127",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.,  2.,  1.,  0.],\n",
       "       [ 4.,  5.,  0.,  1.],\n",
       "       [10., 10.,  0.,  1.]])"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "inputs.values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0e5a8fdb",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
